/**
 * 
 */
package com.xpec.c4.game.utility.wordfilter;

import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;

import com.ms.service.error.ErrorCode;
import com.mysql.jdbc.MysqlErrorNumbers;
import com.xpec.c4.db.hibernate.manager.HibernateManager;
import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.game.utility.wordfilter.db.PlayerNameFilterModel;
import com.xpec.c4.message.ConstantCode;

/**
 * @author TW15010
 *
 */
public class WordFilterDAO {
	/** log4j object */
	private static final Log log = LogFactory.getLog(WordFilterDAO.class);

	/**
	 * 從 db 載入創角關鍵字列表
	 * 
	 * @return
	 */
	public static ArrayList<PlayerNameFilterModel> loadAccountWordsFromDB() {
		Session s = HibernateManager.getSession();
		Query query = s.createQuery("from " + PlayerNameFilterModel.class.getSimpleName());
		@SuppressWarnings("unchecked")
		ArrayList<PlayerNameFilterModel> list = (ArrayList<PlayerNameFilterModel>) query.list();
		HibernateManager.endSession();

		return list;
	}

	/**
	 * 新增過濾字
	 * 
	 * @param word
	 * @param compareTypeStr
	 *            比對方式 {@link WordCompareType}
	 * @return error code, {@link ErrorCode}
	 */
	public static int addWord(String word, String compareTypeStr) {
		if (!GameUtility.isHaveString(word)) {
			return ErrorCode.PNF_INVALID_WORD;
		}

		if (!GameUtility.isNumeric(compareTypeStr)) {
			return ErrorCode.PNF_INVALID_COMPARE_TYPE;
		}

		int compareType = Integer.valueOf(compareTypeStr);
		if (!ConstantCode.isValid(WordCompareType.class, compareType)) {
			return ErrorCode.PNF_INVALID_COMPARE_TYPE;
		}

		PlayerNameFilterModel model = new PlayerNameFilterModel();
		model.setWord(word);
		model.setCompareType(compareType);

		Session s = HibernateManager.txBegin();
		try {
			s.saveOrUpdate(model);
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("add word fail, word=" + word, e);
			}
		}

		int[] errorCode = new int[2];
		boolean res = HibernateManager.txCommitFailRollbackClearSession(errorCode);

		if (log.isInfoEnabled()) {
			log.info("add word word=" + word + " res=" + res);
		}

		if (!res) {
			if (errorCode[0] == MysqlErrorNumbers.ER_DUP_ENTRY) {
				return ErrorCode.PNF_DUPLICATE_WORD;
			}

			return ErrorCode.DB_OPERATION_FAIL;
		}

		return ErrorCode.SUCCESS;
	}

	/**
	 * 更新過濾字
	 * <p>
	 * explain:<br>
	 * explain select * from casino_game.player_name_filter where
	 * db_id='4028b22d5ba4bc7b015ba4bcc4bb0000';<br>
	 * 'id' 'select_type' 'table' 'type' 'possible_keys' 'key' 'key_len' 'ref'
	 * 'rows' 'Extra'<br>
	 * 1 'SIMPLE' 'player_name_filter' 'const' 'PRIMARY' 'PRIMARY' '767' 'const'
	 * 1 ''<br>
	 * 
	 * @param db_id
	 * @param word
	 * @param compareTypeStr
	 *            比對方式 {@link WordCompareType}
	 * @return error code, {@link ErrorCode}
	 */
	public static int updateWord(String db_id, String word, String compareTypeStr) {
		if (!GameUtility.isHaveString(word)) {
			return ErrorCode.PNF_INVALID_WORD;
		}

		if (!GameUtility.isNumeric(compareTypeStr)) {
			return ErrorCode.PNF_INVALID_COMPARE_TYPE;
		}

		int compareType = Integer.valueOf(compareTypeStr);
		if (!ConstantCode.isValid(WordCompareType.class, compareType)) {
			return ErrorCode.PNF_INVALID_COMPARE_TYPE;
		}

		PlayerNameFilterModel model = new PlayerNameFilterModel();
		model.setDb_id(db_id);
		model.setWord(word);
		model.setCompareType(compareType);

		Session s = HibernateManager.txBegin();
		try {
			s.saveOrUpdate(model);
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("update word fail, db_id=" + db_id + " word=" + word, e);
			}
		}

		int[] errorCode = new int[2];
		boolean res = HibernateManager.txCommitFailRollbackClearSession(errorCode);

		if (log.isInfoEnabled()) {
			log.info("update word db_id=" + db_id + " word=" + word + " res=" + res);
		}

		if (!res) {
			if (errorCode[0] == MysqlErrorNumbers.ER_DUP_ENTRY) {
				return ErrorCode.PNF_DUPLICATE_WORD;
			}

			return ErrorCode.DB_OPERATION_FAIL;
		}

		return ErrorCode.SUCCESS;
	}

	/**
	 * 刪除過濾字
	 * <p>
	 * explain:<br>
	 * explain select * from casino_game.player_name_filter where
	 * db_id='4028b22d5ba4bc7b015ba4bcc4bb0000';<br>
	 * 'id' 'select_type' 'table' 'type' 'possible_keys' 'key' 'key_len' 'ref'
	 * 'rows' 'Extra'<br>
	 * 1 'SIMPLE' 'player_name_filter' 'const' 'PRIMARY' 'PRIMARY' '767' 'const'
	 * 1 ''<br>
	 * 
	 * @param db_id
	 * @return error code, {@link ErrorCode}
	 */
	public static int deleteWord(String db_id) {
		Session s = HibernateManager.txBegin();
		Query query = s.createQuery("delete from " + PlayerNameFilterModel.class.getSimpleName()
				+ " where db_id = :db_id");
		query.setString("db_id", db_id);
		query.executeUpdate();
		boolean res = HibernateManager.txCommitFailRollbackClearSession();

		if (log.isInfoEnabled()) {
			log.info("delete word db_id=" + db_id + " res=" + res);
		}

		if (!res) {
			return ErrorCode.DB_OPERATION_FAIL;
		}

		return ErrorCode.SUCCESS;
	}
}
